#include "../include/kasm.h"
#include "../include/defs.h"
#include "../include/kernel.h"
#include "../include/keyboard.h"
#include "../include/kc.h"
#include "../include/video.h"
#include "../include/buffer.h"
#include "../include/shell.h"
#include "../include/mouse.h"
#include "../include/terminal.h"
#include "../include/process.h"
#include "../include/scheduler.h"
#include "../include/memoryPaging.h"
#include "../include/fileSystem/fileSystem.h"

//definiciones de los irq que seran usados
#define IRQ_0 0xFE	//habilita el timertic
#define IRQ_1 0xFD	//habilita el teclado
#define IRQ_2 0xFB	//habilita el pic2
#define IRQ_12 0xEF	//habilita el mousePS/2


DESCR_INT idt[0x81];	/* IDT de 0x80 entradas*/
IDTR idtr;				/* IDTR */

tty ttyArray[MAX_TTY]; //array con todas las terminales
int curTTY; //numero de la terminal actual

extern process_t processes[];	//lista de procesos
extern int currProc;			//proceso actual


//----------------------------------------------------------------------------
//Manejadores de interrupciones

//handler del mouse
void
int_74(unsigned char code) {
	//llamo a la funcion que usa el codigo que genero el mouse
	//si escribio al stdin me devuelve 1
	if (mouseTranslator(&ttyArray[curTTY].stdout, &(ttyArray[curTTY].stdin),
		&(ttyArray[curTTY].mouseCopyBuff), code) == 1) {
		//aviso a los procesos que estaban bloqueados en mi terminal
		//que escribi algo y se deberian desbloquear para leer
		unblockProcesses(curTTY);
	}
}

//handler del teclado
void
int_09(unsigned char c) {
	//funcion que maneja el codigo que genera el teclado
	//si escribio al stdin me devuelve 1
	if (keyTranslator(&(ttyArray[curTTY].stdin), c) == 1) {
		//aviso a los procesos que estaban bloqueados en mi terminal
		//que escribi algo y se deberian desbloquear para leer
		unblockProcesses(curTTY);
	}
}

//handler de la excepcion de page fault
void
pageFault() {
	printf("Page Fault - Process %d killed\n", processes[currProc].pid);
	//mato al proceso que genero la excepcion
	killProc(processes[currProc].pid);
	_sys_yield();
}

/*----------------------------------------------------------------------------
kmain()
Punto de entrada de la imagen*/
//----------------------------------------------------------------------------
int
kmain(void)
{

/* CARGA DE IDT CON LA RUTINA DE ATENCION DE IRQ0    */

	//timer tick
	setup_IDT_entry (&idt[0x08], 0x08, (dword)&_int_08_hand, ACS_INT, 0);
	//teclado
	setup_IDT_entry (&idt[0x09], 0x08, (dword)&_int_09_hand, ACS_INT, 0);
	//page fault
	setup_IDT_entry (&idt[0x0E], 0x08, (dword)&_int_0E_hand, ACS_INT, 0);
	//system calls
	setup_IDT_entry (&idt[0x80], 0x08, (dword)&_int_80_hand, ACS_INT, 0);
	//interrupcion llamada por yield
	setup_IDT_entry (&idt[0x7F], 0x08, (dword)&_int_7F_hand, ACS_INT, 0);
	//mouse
	setup_IDT_entry (&idt[0x74], 0x08, (dword)&_int_74_hand, ACS_INT, 0);

/* Carga de IDTR    */

	idtr.base = 0;
	idtr.base +=(dword) &idt;
	idtr.limit = sizeof(idt)-1;

	_lidt (&idtr);

	_Cli();

/* 	Habilito interrupcion de timer tick(IRQ_0), de keyboard (IRQ_1)
 *  de mouse (IRQ_12) y el PIC2 (IRQ_2) */

	_mascaraPIC1(IRQ_0 & IRQ_1 & IRQ_2);
	_mascaraPIC2(IRQ_12);

	initKeyboard();

	initMouse();

	initPaging();

	initTTYs();

	initFileSystem();

	initScheduler();

	int i;
	char welcomeStr[41], * str = welcomeStr;
	strcpy(welcomeStr, "PontiOS 1.31 - Operating System (tty1)\n\n");
	for (i = 0; i < 8; i++) {
		welcomeStr[36] = i + 1 + '0';
		createProcess("shell", shell, 0, 1, &str, 2, i, 0x2000);
	}

	_Sti();

	//me quedo en un loop aca para no salir
	while(1);

	return 1;
}

